﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Xml;
using System.Xml.Schema;
using System.Text;
using InfoJetSoft.Service.Entity;
using InfoJetSoft.Service.Util;
using InfoJetSoft.Service;

namespace InfoJetSoft.Service.Worker
{
	
	class FormRuleFieldWorker
	{

		//在ValueChangeNode上执行定义在该Node上的Rules.
		public static void runRule(Form form)
		{
			runRule( form, form.ValueChangeNode );
		}

		//运行给定Node上的Rules.
		public static void runRule( Form form, XmlNode changedNode )
		{
            //CID 0221 //2009.02.02 //Begin
            string jetId = DOMUtil.getNodeJetId(changedNode);
            if( jetId == null )
            {
				//对于DataObjectDOM,在2003 Managed Code里设置会触发Rules,没有jetId,不再执行.
                return;
            }
            //CID 0221 //2009.02.02 //End
			runRule( form, changedNode, jetId, new ArrayList() );
		}
		
		//在给定Node上执行DOMHandler。
		//调用者必须保证changedNodeId不为null.只有具有JetId的Node才能参加Rule.
		public static void runRule(Form form, XmlNode changedNode,string changedNodeId, ArrayList runnedList)
		{
			XmlDocument doc = form.XmlDoc;
			XmlElement root = doc.DocumentElement;
			
			ArrayList handlerList = form.Manifest.DomEventHandlerList;
			foreach ( DOMEventHandler handler in handlerList)
			{
				if( !ExpressionUtil.exprContainingNode( handler.Match, changedNode.Name ) ){
					continue;
				}
				foreach (Rule rule in handler.RuleSet.RuleList)
				{
					//如果Rule没有开启,运行下一个Rule.
					if( !rule.Enabled )
					{
						continue;
					}
                    //CID 0921 //2011.05.22 //Begin
                    bool conditionValue = XPathQuery.QueryFieldRuleConditionValue(form, rule, changedNode, changedNodeId);
                    //CID 0921 //2011.05.22 //End
                    if (conditionValue)
					{
						//CID 0474 //2009.12.23 //Begin
						form.Logger.LogUpdate(null);
						//CID 0474 //2009.12.23 //End
						foreach(RuleAction ruleAction in rule.RuleActionList)
						{
							//Don't support switch view on ValueChange.
							if (ruleAction.RuleActionType == RuleAction.iDialogBoxMessage)
							{
								form.ModalMessageList.Add(ruleAction.DialogBoxMessage);
							}
							else if (ruleAction.RuleActionType == RuleAction.iDialogBoxExpression)
							{
                                //CID 0921 //2011.05.22 //Begin
                                string actionValue = XPathQuery.QueryFieldRuleActionValue(form, ruleAction, changedNode, changedNodeId);
                                if (actionValue != null)
                                {
                                    form.ModalMessageList.Add(actionValue);
                                }
                                //CID 0921 //2011.05.22 //End
                            }
							else if (ruleAction.RuleActionType == RuleAction.iAssignment)
							{
								List<XmlNode> targetXmlNodeList = ExtGetDOMSelector.selectNodes(form, changedNode, ruleAction.AssignmentTargetField, form.XmlNsResolver);
								if (targetXmlNodeList != null && targetXmlNodeList.Count > 0)
								{
									string exprValue = null;
									string assignExpr = ruleAction.AssignmentExpression.Trim();
									if (assignExpr.StartsWith("\"") && assignExpr.EndsWith("\""))
									{
										if (assignExpr.Length > 1)
										{
											//去掉常量前后的引号.
											exprValue = assignExpr.Substring(1, assignExpr.Length - 2);
										}
										else
										{
											exprValue = assignExpr;
										}
									}
									else
									{
                                        //CID 0921 //2011.05.22 //Begin
                                        string actionValue = XPathQuery.QueryFieldRuleActionValue(form, ruleAction, changedNode, changedNodeId);
                                        if (actionValue != null)
                                        {
                                            exprValue = actionValue;
                                        }
                                        //CID 0921 //2011.05.22 //End
									}
									if (exprValue != null)
									{
										//将AssignmentAction添加到已运行过的ArrayList中.
										runnedList.Add( ruleAction );
										foreach (XmlNode targetNode in targetXmlNodeList)
										{
											if( DOMUtil.setNodeValue( targetNode, exprValue ) )
											{
												//CID 0451 //2009.11.09 //Begin
												SchemaPSVI.checkXsiNil( form, targetNode );
												//CID 0451 //2009.11.09 //End

												FormUtil.updateFieldValue( form, targetNode );

												//执行由Rule Assignment引发的Form Code.
												string path = DOMUtil.getNodePath( targetNode );
												string targetId = DOMUtil.getNodeJetId( targetNode );
												if( targetId != null )
												{
													//CID 1231 //2012.08.02 //Comment
													//if( runnedList.Count < JetConstant.MAX_LOOP_COUNT )
													//{
														FormRuleFieldWorker.runRule( form, targetNode, targetId, runnedList );
													//}
                                                    //CID 1231 //2012.08.02 //End
												}
												//执行由Rule Assignment引发的Default Value计算.
												FormCalculatedFieldWorker.calculateValueNode( form, targetNode );
												//执行由Rule Assignment计算引发的OnAfterChange.
												FormCodeDispatchWorker.OnValueNodeAfterChange( form, targetNode );
											}
										}
									}
								}
							}
							else if(ruleAction.RuleActionType == RuleAction.iQueryAction)
							{
								string queryName = ManifestUtil.getQueryName( form.Manifest );
								if( queryName != null && queryName.Equals( ruleAction.QueryDataObjectName ) )
								{
                                    //CID 1142 //2012.03.20 //Begin
									FormDataQueryWorker.query( form, false );
                                    //CID 1142 //2012.03.20 //End
								}
								else
								{
									FormDataLoadWorker.loadDataObjectByName(form, ruleAction.QueryDataObjectName);
                                }
                                //CID 1138 //2012.03.19 //Begin
                                if (form.OperationFailed)
                                {
                                    break;
                                }
                                //CID 1138 //2012.03.19 //End
							}
							else if(ruleAction.RuleActionType == RuleAction.iSubmitAction)
                            {
                                //CID 1137 //2012.03.17 //Begin
                                FormDataSubmitWorker.submitByRuleAction(form, ruleAction);
                                if (form.OperationFailed)
                                {
                                    break;
                                }
                                //CID 1137 //2012.03.19 //End
							}
							//CID 0369 //2009.07.18 //Begin
							else if(ruleAction.RuleActionType == RuleAction.iOpenNewDocumentAction)
							{
								if( ruleAction.SolutionURI.Equals( "#PublishUrl#" ) )
								{
									form.NewFormPublishUrl = form.HttpContext.Server.UrlEncode( form.Manifest.PublishUrl );
								}
								else
								{
									form.NewFormPublishUrl = form.HttpContext.Server.UrlEncode( ruleAction.SolutionURI );
								}
							}
                            //CID 0369 //2009.07.18 //End
                            //CID 0604 //2010.06.10 //Begin
                            else if (ruleAction.RuleActionType == RuleAction.iChangeAdapterProperty)
                            {
                                if (ruleAction.AdapterProperty != null && ruleAction.AdapterProperty.Equals("FileURL"))
                                {
                                    //CID 0921 //2011.05.22 //Begin
                                    string actionValue = XPathQuery.QueryFieldRuleActionValue(form, ruleAction, changedNode, changedNodeId);
                                    //CID 0921 //2011.05.22 //End
                                    if (actionValue != null)
                                    {
                                        DataFileAdapter templateFileAdapter = null;
                                        foreach (object dataAdapter in form.Manifest.DataAdapterList)
                                        {
                                            if (dataAdapter is DataFileAdapter)
                                            {
                                                DataFileAdapter fileAdapter = (DataFileAdapter)dataAdapter;
                                                if (fileAdapter.Name.Equals(ruleAction.Adapter))
                                                {
                                                    templateFileAdapter = fileAdapter;
                                                    break;
                                                }
                                            }
                                        }
                                        DataFileAdapter currentFileAdapter = (DataFileAdapter)DataAdapterTableUtil.getCurrentAdapter(form, templateFileAdapter);
                                        currentFileAdapter.FileUrl = actionValue;
                                    }
                                }
                            }
                            //CID 0604 //2010.06.10 //End
						} // end ruleActionList
						if (rule.ExitRuleSet)
						{
							break;
						}
					}// end of rule condition true
				}//end of ruleSet
			}
		}
		
	}
}